gusucode.com > VC++ 界面很酷的一款多媒体播放器 > VC++ 界面很酷的一款多媒体播放器/gusucode/xMedia代码注释中/playlist.cpp
//Download by http://www.NewXing.com /**************************************** * File: playlist.cpp * * Last modified: 2004.2.15 * * Author: Yuanyi-Zhang * * Version: 0.0.1.0 * * CopyLeft 2004 xMedia team * ****************************************/ /**************************************************************** * * * This file may be distributed and/or modified under the terms * * of the GNU General Public License version 2 as published by * * the Free Software Foundation and appearing in the file * * LICENSE.GPL included in the packaging of this file. * * * ****************************************************************/ #pragma warning(disable:4786) #include <tchar.h> #include <windows.h> #include <commctrl.h> #include <shlobj.h> #include <assert.h> #include <fstream> #include "util.h" #include "messagedef.h" #include "playlist.h" ////////////////////////////////// PlayList::PlayList(): m_hWnd( NULL ), m_ErrorString( _T("") ), m_HasCreated(false), m_ClassName( _T("PlayList") ), m_lpIL(0), m_LButtonDown(false), m_Show(false) { m_hDCBack = NULL; m_hBmpBack = NULL; m_hMainBmp = NULL; m_hMaskBmp = NULL; m_hElemBmp = NULL; m_curNum = -1; m_hMenuAdd = m_hMenuRem = m_hMenuLOP = m_hMenuSel = NULL; _tcscpy( tInitDir, _T("") ); } ///////////////////////////// //注册窗口类 BOOL PlayList::RegisterClass( HINSTANCE hInstance ) { WNDCLASSEX wndclass; ZeroMemory(&wndclass, sizeof(wndclass)); //Window class for the main application parent window wndclass.cbSize = sizeof(wndclass); wndclass.style = 0; wndclass.lpfnWndProc = WndProc; wndclass.cbClsExtra = 0; wndclass.cbWndExtra = 0; wndclass.hInstance = hInstance; wndclass.hIcon = 0; wndclass.hCursor = LoadCursor(NULL, IDC_ARROW); wndclass.hbrBackground = (HBRUSH)(COLOR_BTNFACE+1); wndclass.lpszMenuName = 0; wndclass.lpszClassName = m_ClassName.c_str(); wndclass.hIconSm = 0; return RegisterClassEx(&wndclass); } ////////////////////////////////// //创建播放列表 bool PlayList::Create( HINSTANCE hInstance, HWND Parent) { if( m_HasCreated ) { m_ErrorString=_T("错误,重复创建主窗口!"); return false; } if( !RegisterClass( hInstance ) ) { m_ErrorString=_T("注册窗口类失败!"); return false; } MDICREATESTRUCT mdic; memset(& mdic, 0, sizeof(mdic)); mdic.lParam = (LPARAM) this; HWND hWnd=CreateWindowEx( WS_EX_TOOLWINDOW, m_ClassName.c_str(), NULL, WS_POPUP|LVS_EX_ONECLICKACTIVATE, 0, 0, 100, 100, Parent, 0, hInstance, &mdic ); if(hWnd==NULL) { m_ErrorString = _T( "创建播放列表失败,不明错误!" ); return false; } if( !InitTooltips( hWnd, hInstance ) ) { return false; } m_ErrorString = _T( "" ); return true; } ///////////////////////////////////// //读取皮肤配置 bool PlayList::LoadSkinConfig() { if( m_lpIL == NULL ) { m_ErrorString = _T("未设置配置文件"); return false; } string str; str = m_lpIL->Get( _T( "plwindowrect" ) ); if( str.compare( _T( "" ) ) == 0 ) { m_ErrorString = _T("配置文件不完整,无法读取所需信息!"); return false; } m_WndRect = StringToRect( str ); str = m_lpIL->Get( _T( "pllistwndrect" ) ); if( str.compare( _T( "" ) ) == 0 ) { m_ErrorString = _T("配置文件不完整,无法读取所需信息!"); return false; } m_ListRect = StringToRect( str ); str = m_lpIL->Get( _T( "pllistwndbkcolor" ) ); if( str.compare( _T( "" ) ) == 0 ) { m_ErrorString = _T("配置文件不完整,无法读取所需信息!"); return false; } m_ListBkColor = StringToColorRef( str ); str = m_lpIL->Get( _T( "pllistwndfontcolor" ) ); if( str.compare( _T( "" ) ) == 0 ) { m_ErrorString = _T("配置文件不完整,无法读取所需信息!"); return false; } m_ListFontColor = StringToColorRef( str ); m_SkinName = m_lpIL->Get( _T( "skinname" ) ); m_vecElement.push_back( Element( _T("plclosebutton"), m_lpIL, XM_PLCLOSEBUTTON, true ) ); m_vecElement.push_back( Element( _T("pladdbutton"), m_lpIL, XM_PLADDBUTTON, true ) ); m_vecElement.push_back( Element( _T("plrembutton"), m_lpIL, XM_PLREMBUTTON, true ) ); m_vecElement.push_back( Element( _T("pllopbutton"), m_lpIL, XM_PLLOPBUTTON, true ) ); m_vecElement.push_back( Element( _T("plmiscbutton"), m_lpIL, XM_PLMISCBUTTON, true ) ); m_vecElement.push_back( Element( _T("plselbutton"), m_lpIL, XM_PLSELBUTTON, true ) ); m_vecElement.push_back( Element( _T("plplaybutton"), m_lpIL, XM_PLPLAYBUTTON, true ) ); m_vecElement.push_back( Element( _T("plnextbutton"), m_lpIL, XM_PLNEXTBUTTON, true ) ); m_vecElement.push_back( Element( _T("plpausebutton"), m_lpIL, XM_PLPAUSEBUTTON, true ) ); m_vecElement.push_back( Element( _T("plprevbutton"), m_lpIL, XM_PLPREVBUTTON, true ) ); m_vecElement.push_back( Element( _T("plstopbutton"), m_lpIL, XM_PLSTOPBUTTON, true ) ); return true; } ////////////////////////////////////// //将窗口消息发送到播放列表消息处理窗口 LRESULT CALLBACK PlayList::WndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) { PlayList *pMainWnd; if ( uMsg==WM_NCCREATE ) { assert( ! IsBadReadPtr((void *) lParam, sizeof(CREATESTRUCT)) ); MDICREATESTRUCT * pMDIC = (MDICREATESTRUCT *) ((LPCREATESTRUCT) lParam)->lpCreateParams; pMainWnd = (PlayList *) (pMDIC->lParam); assert( ! IsBadReadPtr(pMainWnd, sizeof(PlayList)) ); SetWindowLong(hWnd, GWL_USERDATA, (LONG) pMainWnd); } else pMainWnd=(PlayList *)GetWindowLong(hWnd, GWL_USERDATA); return pMainWnd->MsgProc( hWnd, uMsg, wParam, lParam ); } ////////////////////////////////////////// //处理播放列表窗口消息 long PlayList::MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) { POINT p; switch( uMsg ) { case WM_CREATE: m_hWnd = hWnd; if( !initials( hWnd ) ) { MessageBox( hWnd, GetErrorString().c_str(), "错误", MB_OK|MB_ICONWARNING ); } break; case WM_PAINT: onDraw(); break; case WM_LBUTTONDOWN: SetCapture( hWnd ); p.x = LOWORD(lParam); p.y = HIWORD(lParam); ClientToScreen( hWnd, &p ); onLButtonDown( p ); break; case WM_MOUSEMOVE: GetCursorPos( &p ); onMouseMove( p ); break; case WM_LBUTTONUP: ReleaseCapture(); p.x = LOWORD(lParam); p.y = HIWORD(lParam); ClientToScreen( hWnd, &p ); onLButtonUp( p ); break; case WM_COMMAND: switch( LOWORD( wParam ) ) { case IDM_ADDFILE: addFileToList(); break; case IDM_ADDDIR: addDirToList(); break; case IDM_REMALL: ListView_DeleteAllItems( m_hWndList ); m_vecFile.erase( m_vecFile.begin(), m_vecFile.end() ); break; case IDM_REMSEL: RemSel(); break; case IDM_REMUNSEL: RemUnSel(); break; case IDM_SELALL: SelAll(); break; case IDM_UNSEL: UnSel(); break; case IDM_SELOTHER: SelOther(); break; case IDM_LOADLIST: loadList(); break; case IDM_SAVELIST: saveList(); break; } break; case WM_NOTIFY: switch (((LPNMHDR) lParam)->code) { case LVN_ITEMACTIVATE: //有项目被双击则播放此项目 ListView_SetHotItem( m_hWndList, ((LPNMLISTVIEW)lParam)->iItem ); PostThreadMessage( GetCurrentThreadId(), MC_PLAY, 0l, 0l ); break; } break; case XM_GETFILEINFO: getFileInfo(); break; case XM_PLCLOSEBUTTON: switch( wParam ) { case ELEM_LBUTTONDOWN: Show(); break; } break; case XM_PLPLAYBUTTON: switch( wParam ) { case ELEM_LBUTTONDOWN: PostThreadMessage( GetCurrentThreadId(), MC_PLAY, 0l, 0l ); break; } break; case XM_PLSTOPBUTTON: switch( wParam ) { case ELEM_LBUTTONDOWN: PostThreadMessage( GetCurrentThreadId(), MC_STOP, 0l, 0l ); break; } break; case XM_PLPAUSEBUTTON: switch( wParam ) { case ELEM_LBUTTONDOWN: PostThreadMessage( GetCurrentThreadId(), MC_PAUSE, 0l, 0l ); break; } break; case XM_PLPREVBUTTON: switch( wParam ) { case ELEM_LBUTTONDOWN: PostThreadMessage( GetCurrentThreadId(), MC_PLAYPREV, 0l, 0l ); break; } break; case XM_PLNEXTBUTTON: switch( wParam ) { case ELEM_LBUTTONDOWN: PostThreadMessage( GetCurrentThreadId(), MC_PLAYNEXT, 0l, 0l ); break; } break; case XM_PLADDBUTTON: switch( wParam ) { case ELEM_LBUTTONDOWN: popupMenu( m_hMenuAdd, _T("pladdbutton") ); break; } break; case XM_PLREMBUTTON: switch( wParam ) { case ELEM_LBUTTONDOWN: popupMenu( m_hMenuRem, _T("plrembutton") ); break; } break; case XM_PLLOPBUTTON: switch( wParam ) { case ELEM_LBUTTONDOWN: popupMenu( m_hMenuLOP, _T("pllopbutton") ); break; } break; case XM_PLSELBUTTON: switch( wParam ) { case ELEM_LBUTTONDOWN: popupMenu( m_hMenuSel, _T("plselbutton") ); break; } break; } return DefWindowProc( hWnd, uMsg, wParam, lParam ); } ////////////////////////////////////// //初始化播放列表 bool PlayList::initials( HWND hwnd ) { if( !InitDC() ) { return false; } SetWindowSize(); if( !LoadResource() ) { return false; } SetWindowRegion(); if( !initMenu() ) { return false; } if( !createList( hwnd ) ) { return false; } m_HasCreated = true; return true; } ////////////////////////// //初始化DC bool PlayList::InitDC() { if( m_hDCBack ) { DeleteObject( m_hDCBack ); } if( m_hBmpBack ) { DeleteObject( m_hBmpBack ); } HDC hdc; hdc = GetDC( m_hWnd ); m_hDCBack = CreateCompatibleDC( hdc ); m_hBmpBack = CreateCompatibleBitmap( hdc, m_WndRect.right - m_WndRect.left, m_WndRect.bottom - m_WndRect.top); if( !m_hDCBack || !m_hBmpBack ) { m_ErrorString = _T("初始化DC失败!"); return false; } SelectObject( m_hDCBack, m_hBmpBack ); return true; } /////////////////////// //释放资源 void PlayList::ReleaseResource() { if( m_hDCBack ) { DeleteObject( m_hDCBack ); } if( m_hBmpBack ) { DeleteObject( m_hBmpBack ); } if( m_hMaskBmp ) { DeleteObject( m_hMaskBmp ); } if( m_hMainBmp ) { DeleteObject( m_hMainBmp ); } if( m_hElemBmp ) { DeleteObject( m_hElemBmp ); } if( m_hMenuAdd) { DestroyMenu( m_hMenuAdd); } if( m_hMenuRem) { DestroyMenu( m_hMenuRem); } if( m_hMenuLOP) { DestroyMenu( m_hMenuLOP); } if( m_hMenuSel) { DestroyMenu( m_hMenuSel); } } //////////////////// //处理OnDraw消息 bool PlayList::onDraw( ) { HDC hdc,hdcImg; PAINTSTRUCT ps; hdc = BeginPaint( m_hWnd, &ps ); hdcImg = CreateCompatibleDC( hdc ); SelectObject( hdcImg, m_hMainBmp ); BitBlt( m_hDCBack, 0, 0, m_WndRect.right - m_WndRect.left, m_WndRect.bottom - m_WndRect.top, hdcImg, 0, 0, SRCCOPY ); vector<Element>::iterator ite; for( ite = m_vecElement.begin(); ite != m_vecElement.end(); ite++ ) { if( !ite->onDraw( m_hDCBack, m_hElemBmp ) ) { return false; } } BitBlt( hdc, 0, 0, m_WndRect.right - m_WndRect.left, m_WndRect.bottom - m_WndRect.top, m_hDCBack, 0, 0, SRCCOPY ); EndPaint( m_hWnd, &ps ); DeleteObject( hdcImg ); DeleteObject( hdc ); return true; } //////////////////// //读取位图资源 bool PlayList::LoadResource() { if( m_hMaskBmp ) { DeleteObject( m_hMaskBmp ); } if( m_hMainBmp ) { DeleteObject( m_hMainBmp ); } if( m_hElemBmp ) { DeleteObject( m_hElemBmp ); } string maskBmp,mainBmp,elemBmp; maskBmp = _T( "skin\\" ) + m_SkinName + _T( "\\plmask.bmp" ); mainBmp = _T( "skin\\" ) + m_SkinName + _T( "\\plmain.bmp" ); elemBmp = _T( "skin\\" ) + m_SkinName + _T( "\\plelement.bmp" ); m_hMaskBmp = (HBITMAP)LoadImage( NULL, maskBmp.c_str(), IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE|LR_CREATEDIBSECTION ); if( !m_hMaskBmp ) { m_ErrorString = _T("无法读取文件:") + maskBmp; return false; } m_hMainBmp = (HBITMAP)LoadImage( NULL, mainBmp.c_str(), IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE|LR_CREATEDIBSECTION ); if( !m_hMainBmp ) { m_ErrorString = _T("无法读取文件:") + mainBmp; return false; } m_hElemBmp = (HBITMAP)LoadImage( NULL, elemBmp.c_str(), IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE|LR_CREATEDIBSECTION ); if( !m_hElemBmp ) { m_ErrorString = _T("无法读取文件:") + elemBmp; return false; } return true; } //////////////////////////// //初始化工具提示 bool PlayList::InitTooltips( HWND hwnd, HINSTANCE hInst ) { HWND hwndTT; //Tooltip控件句柄 //创建Tooltip控件 hwndTT = CreateWindowEx(WS_EX_TOPMOST, TOOLTIPS_CLASS, NULL, WS_POPUP | TTS_NOPREFIX | TTS_ALWAYSTIP, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, hwnd, NULL, hInst, NULL ); if( hwndTT == NULL ) { m_ErrorString = _T("创建工具提示窗口失败!"); return false; } SetWindowPos(hwndTT, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE); //这个结构体存储Tooltip控件的相关信息 TOOLINFO ti; unsigned int uid = 0; //初始化ti结构体成员 ti.cbSize = sizeof(TOOLINFO); ti.uFlags = TTF_SUBCLASS; ti.hwnd = hwnd; ti.hinst = hInst; ti.uId = uid; TCHAR tcsTooltip[256]; vector<Element>::iterator ite; RECT rect; string str; for( ite = m_vecElement.begin(); ite != m_vecElement.end(); ite++ ) { rect = ite->getRectPos(); str = ite->getTooltip(); if( (rect.left == rect.right && rect.top == rect.bottom) || str.compare( _T("") ) == 0 ) { continue; } strcpy( tcsTooltip, str.c_str() ); ti.lpszText = tcsTooltip; ti.rect = rect; //添加工具提示 SendMessage(hwndTT, TTM_ADDTOOL, 0, (LPARAM) (LPTOOLINFO) &ti); } return true; } //////////////////////////// //设置窗口可见区域 void PlayList::SetWindowRegion() { HRGN hWndRgn; RECT clientRect,wndRect; GetClientRect( m_hWnd, &clientRect ); GetWindowRect( m_hWnd, &wndRect ); POINT start = { 0, 0 }; ClientToScreen( m_hWnd, &start ); hWndRgn = CreateRectRgn( start.x - wndRect.left, start.y - wndRect.top, clientRect.right - clientRect.left + start.x - wndRect.left, clientRect.bottom - clientRect.top + start.y - wndRect.top ); BITMAP bmp; GetObject(m_hMaskBmp, sizeof(bmp), &bmp); HRGN temp; HDC hdc = GetDC( m_hWnd ); HDC hdcImg = CreateCompatibleDC( hdc ); ReleaseDC( m_hWnd, hdc ); SelectObject( m_hDCBack, m_hBmpBack ); SelectObject( hdcImg, m_hMaskBmp ); BitBlt( m_hDCBack, 0, 0, m_WndRect.right - m_WndRect.left, m_WndRect.bottom - m_WndRect.top, hdcImg, 0, 0, SRCCOPY ); DeleteObject( hdcImg ); for( int i = 0; i < bmp.bmWidth; i++ ) { for( int j = 0; j < bmp.bmHeight; j++ ) { if( GetPixel( m_hDCBack, i, j ) == RGB( 255, 255, 255 ) ) { temp = CreateRectRgn( start.x - wndRect.left + i, start.y - wndRect.top + j, start.x - wndRect.left + i + 1, start.y - wndRect.top + j + 1 ); CombineRgn( hWndRgn, hWndRgn, temp, RGN_XOR ); DeleteObject( temp ); } } } SetWindowRgn( m_hWnd, hWndRgn, false ); } //////////////////////////// //处理鼠标左键按下消息 void PlayList::onLButtonDown( POINT p ) { m_LButtonDown = true; m_clickPos = p; bool isElemClicked = false; ScreenToClient( m_hWnd, &p ); vector<Element>::iterator ite; RECT validRect; for( ite = m_vecElement.begin(); ite != m_vecElement.end(); ite++ ) { if( ite->onLButtonDown( p ) ) { isElemClicked = true; validRect = ite->getRectPos(); InvalidateRect( m_hWnd, &validRect, false ); } } if( isElemClicked ) { m_LButtonDown = false; } } ////////////////////////// //处理鼠标移动消息 void PlayList::onMouseMove( POINT p ) { RECT wndRect; GetWindowRect( m_hWnd, &wndRect ); if( m_LButtonDown ) { wndRect.left += p.x - m_clickPos.x; wndRect.right += p.x - m_clickPos.x; wndRect.bottom += p.y - m_clickPos.y; wndRect.top += p.y - m_clickPos.y; m_clickPos = p; MoveWindow(m_hWnd, wndRect.left, wndRect.top, wndRect.right - wndRect.left, wndRect.bottom - wndRect.top, true ); } else { ScreenToClient( m_hWnd, &p ); vector<Element>::iterator ite; RECT validRect; for( ite = m_vecElement.begin(); ite != m_vecElement.end(); ite++ ) { if( ite->onMouseMove( p ) ) { validRect = ite->getRectPos(); InvalidateRect( m_hWnd, &validRect, false ); } } } } ///////////////////////// //处理鼠标左键松开消息 void PlayList::onLButtonUp( POINT p ) { if( m_LButtonDown ) { m_LButtonDown = false; } else { ScreenToClient( m_hWnd, &p ); vector<Element>::iterator ite; RECT validRect; for( ite = m_vecElement.begin(); ite != m_vecElement.end(); ite++ ) { if( ite->onLButtonUp( p ) ) { validRect = ite->getRectPos(); InvalidateRect( m_hWnd, &validRect, false ); } } } } /////////////////////////////////// //通过按钮名称获取按钮 Element* PlayList::getElementByName( string str ) { vector<Element>::iterator ite; for( ite = m_vecElement.begin(); ite != m_vecElement.end(); ite++ ) { if( str.compare( ite->getName() ) == 0 ) break; } if( ite == m_vecElement.end() ) { return NULL; } return ite; } /////////////////////////////////// //创建列表框控件 bool PlayList::createList( HWND hwnd ) { HINSTANCE hInst = (HINSTANCE) GetWindowLong( hwnd, GWL_HINSTANCE ); m_hWndList = CreateWindowEx( WS_EX_ACCEPTFILES| LVS_EX_FULLROWSELECT|LVS_EX_TWOCLICKACTIVATE, WC_LISTVIEW, _T(""), WS_CHILD | LVS_REPORT |LVS_NOCOLUMNHEADER| WS_VISIBLE, 0,0,100,100, hwnd, NULL, hInst, NULL); if( m_hWndList == NULL ) { m_ErrorString = _T("创建播放列表失败!"); return false; } MoveWindow( m_hWndList, m_ListRect.left, m_ListRect.top, m_ListRect.right - m_ListRect.left, m_ListRect.bottom - m_ListRect.top, true ); LV_COLUMN lvc; lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM; lvc.iSubItem = 1; lvc.pszText = _T("文件名"); lvc.cx = m_ListRect.right -m_ListRect.left - 80; lvc.fmt = LVCFMT_LEFT; ListView_InsertColumn( m_hWndList, 0, &lvc ); lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM; lvc.iSubItem = 1; lvc.pszText = _T("长度"); lvc.cx = 60; lvc.fmt = LVCFMT_RIGHT; ListView_InsertColumn( m_hWndList, 1, &lvc); ListView_SetBkColor( m_hWndList, m_ListBkColor ); ListView_SetTextBkColor( m_hWndList, m_ListBkColor ); ListView_SetTextColor( m_hWndList, m_ListFontColor ); return true; } ////////////////////////////// //初始化弹出菜单 bool PlayList::initMenu() { m_hMenuAdd = CreatePopupMenu( ); InsertMenu( m_hMenuAdd, -1, MF_BYCOMMAND, IDM_ADDFILE, _T("添加文件...") ); InsertMenu( m_hMenuAdd, -1, MF_BYCOMMAND|MF_BYPOSITION|MF_STRING, IDM_ADDDIR, _T("添加目录...") ); m_hMenuRem = CreatePopupMenu( ); InsertMenu( m_hMenuRem, -1, MF_BYCOMMAND|MF_BYPOSITION|MF_STRING, IDM_REMALL, _T("删除全部...") ); InsertMenu( m_hMenuRem, -1, MF_BYCOMMAND|MF_BYPOSITION|MF_STRING, IDM_REMSEL, _T("删除选中..." ) ); InsertMenu( m_hMenuRem, -1, MF_BYCOMMAND|MF_BYPOSITION|MF_STRING, IDM_REMUNSEL, _T("删除未选...") ); m_hMenuLOP = CreatePopupMenu( ); InsertMenu( m_hMenuLOP, -1, MF_BYCOMMAND|MF_BYPOSITION|MF_STRING, IDM_LOADLIST, _T("导入列表...") ); InsertMenu( m_hMenuLOP, -1, MF_BYCOMMAND|MF_BYPOSITION|MF_STRING, IDM_SAVELIST, _T("保存列表...") ); m_hMenuSel = CreatePopupMenu( ); InsertMenu( m_hMenuSel, -1, MF_BYCOMMAND|MF_BYPOSITION|MF_STRING, IDM_SELALL, _T("全部选定...") ); InsertMenu( m_hMenuSel, -1, MF_BYCOMMAND|MF_BYPOSITION|MF_STRING, IDM_SELOTHER, _T("反向选定...") ); InsertMenu( m_hMenuSel, -1, MF_BYCOMMAND|MF_BYPOSITION|MF_STRING, IDM_UNSEL, _T("取消选择...") ); if( !m_hMenuAdd || !m_hMenuRem || !m_hMenuLOP || !m_hMenuSel ) { m_ErrorString = _T( "初始化菜单失败!" ); return false; } return true; } ///////////////////// //显示弹出菜单 void PlayList::popupMenu( HMENU hMenu, string e ) { Element *elem = getElementByName( e ); if( elem == NULL ) { return; } RECT rect = elem->getRectPos(); POINT p; p.x = rect.right; p.y = rect.top; ClientToScreen( m_hWnd, &p ); TrackPopupMenu( hMenu, TPM_LEFTALIGN | TPM_LEFTBUTTON, p.x, p.y, 0, m_hWnd, &rect ); } //////////////////////////// //检查用户选择的文件名后缀是否被支持 bool PlayList::IsValidFileName(string fname) { string fext; size_t ip; ip = fname.find_last_of("."); if( ip == fname.npos) return false; fext = fname.substr(ip+1); TCHAR tMediaFilter[][5]={ _T("wav"), _T("wma"), _T("wmv"), _T("asf"), _T("mpeg"), _T("avi"), _T("mov"), _T("aiff"), _T("au"), _T("snd"), _T("midi"), _T("MP3") }; int num = 12; int i; for( i = 0; i < num; i++ ) { if( _tcsicmp( tMediaFilter[i], fext.c_str() ) == 0 ) return true; } return false; } //////////////////////////// //添加文件夹内的所有按钮到播放列表 void PlayList::AddDir(TCHAR* tPathName) { TCHAR curDir[256]; GetCurrentDirectory(256,curDir); SetCurrentDirectory(tPathName); TCHAR tFileName[MAX_PATH]; HANDLE fileHandle; WIN32_FIND_DATA findData; fileHandle = FindFirstFile(_T("*.*"), &findData ); while ( fileHandle != INVALID_HANDLE_VALUE ) { if( !(findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) { _stprintf(tFileName,_T("%s\\%s"),tPathName, findData.cFileName); if(IsValidFileName(tFileName)) { m_vecFile.push_back( FileInfo( tFileName ) ); } } else { if(strcmp(findData.cFileName,".")&& strcmp(findData.cFileName,"..")) { _stprintf(tFileName,_T("%s\\%s"),tPathName, findData.cFileName); AddDir(tFileName); } } //打开下一文件 if (!FindNextFile( fileHandle, &findData )) break; } FindClose( fileHandle );//关闭文件 SetCurrentDirectory(curDir); PostThreadMessage( GetCurrentThreadId( ), XM_GETFILEINFO, 0, 0 ); } ///////////////////////// //显示目录选择对话框 void PlayList::addDirToList() { BROWSEINFO bs; LPITEMIDLIST lpdl; TCHAR tPathName[MAX_PATH]; memset( &bs, 0, sizeof(bs) ); bs.hwndOwner = m_hWnd; bs.pidlRoot = NULL; bs.pszDisplayName = tPathName; bs.lpszTitle = "请选择目录"; bs.ulFlags = BIF_RETURNONLYFSDIRS; lpdl = SHBrowseForFolder(&bs); if( SHGetPathFromIDList( lpdl, tPathName ) ) { AddDir( tPathName ); } } ///////////////////////// //从文件读取播放列表 void PlayList::loadList() { TCHAR fileName[MAX_PATH] = _T(""); TCHAR tFilter[]=_T("播放列表(*.m3u)\0*.m3u;\0"); if( !showOpenDialog( m_hWnd, fileName, tFilter, tInitDir ) ) return; ListView_DeleteAllItems( m_hWndList ); m_vecFile.erase( m_vecFile.begin(), m_vecFile.end() ); ifstream in; in.open(fileName); TCHAR tBuffer[MAX_PATH]; string strBuf,strTemp,strDriver,strDir; size_t ip; //获取M3U文件存放路径 strBuf=fileName; ip=strBuf.find_first_of('\\'); strDriver=strBuf.substr(0,ip); ip=strBuf.find_last_of('\\'); strDir=strBuf.substr(0,ip); //读取第一行并判断是否是有效的M3U文件 in.getline(tBuffer,MAX_PATH); if(_tcscmp(tBuffer,_T("#EXTM3U"))) return; while(in.good()) { //读取第一行 in.getline(tBuffer,MAX_PATH); strBuf=tBuffer; //检查是否有冒号 ip=strBuf.find_first_of(':'); if(ip==strBuf.npos) { continue; } //检查行首是否为#EXTINF,不是则跳过此行 strTemp=strBuf.substr(0,ip); strBuf=strBuf.substr(ip+1); if(strTemp.compare(_T("#EXTINF"))) continue; //获取此项目播放时间及标题 ip=strBuf.find_first_of(','); strTemp=strBuf.substr(0,ip); strBuf=strBuf.substr(ip+1); //获取文件实际存放路径 in.getline(tBuffer,MAX_PATH); strBuf=tBuffer; //检查路径是否完全,如果不完全,则以M3U文件 //的存放目录补全 ip=strBuf.find_first_of('\\'); if(ip==strBuf.npos) { strBuf=strDir+"\\"+strBuf; } ip=strBuf.find_first_of(':'); if(ip==strBuf.npos) { strBuf=strDriver+strBuf; } //将其添加到播放列表中 m_vecFile.push_back(strBuf); } in.close(); PostThreadMessage( GetCurrentThreadId( ), XM_GETFILEINFO, 0, 0 ); } ///////////////////////// //保存播放列表为。M3U文件 void PlayList::saveList( ) { TCHAR tFileName[MAX_PATH]=_T(""); //得到要保存的文件名 if(!ShowSaveDialog( m_hWnd ,tFileName)) { return; } //保存用户选择的M3U文件 ofstream out; out.open(tFileName); vector<FileInfo>::iterator ite; if(out.good()) { //写入M3U文件标志 out<<_T("#EXTM3U")<<endl; for(ite=m_vecFile.begin();ite!=m_vecFile.end();ite++) { //写入项目信息 out<<_T("#EXTINF:")<<0<<_T(",")<<ite->getFileName()<<endl <<ite->getPath()<<endl; } } out.close(); } ///////////////////////// //添加文件到列表 void PlayList::addFileToList() { TCHAR fileName[MAX_PATH*4] = _T(""); TCHAR tFilter[]=_T("所有支持类型\0*.wav;*.wma;*.wmv;*.asf;*.mpeg;*.avi;*.mov;*.AIFF;*.au;*.snd;*.midi;*.mp3;\0"); if( !showOpenDialog( m_hWnd, fileName, tFilter, tInitDir ) ) return; string str,item,dir; int i; for( i = 0; i < MAX_PATH * 4; i++ ) { if( fileName[i] == '\0' ) fileName[i] = '*'; } for( i = MAX_PATH * 4 - 1; i > 0; i-- ) { if( fileName[i] == '*' ) fileName[i] = '\0'; if( fileName[i - 1] != '*' ) break; } str = fileName; size_t ip; ip = str.find_first_of( '*' ); item = str.substr( 0, ip ); if( ip == str.npos ) m_vecFile.push_back( FileInfo( item ) ); else { dir = item; str = str.substr( ip+1 ); while( (ip = str.find_first_of( '*' ) ) != str.npos ) { item = str.substr( 0, ip ); m_vecFile.push_back( FileInfo( dir + "\\" + item ) ); str = str.substr( ip + 1 ); } m_vecFile.push_back( FileInfo( dir + "\\" + str ) ); } PostThreadMessage( GetCurrentThreadId( ), XM_GETFILEINFO, 0, 0 ); } ///////////////////////////// //获取文件信息 void PlayList::getFileInfo() { vector<FileInfo>::iterator ite; LV_ITEM lvi; TCHAR tTitle[MAX_PATH]; int iItem; lvi.mask = LVIF_TEXT; lvi.iItem = ListView_GetItemCount( m_hWndList ); lvi.iSubItem = 0; for( ite = m_vecFile.begin(); ite != m_vecFile.end(); ite++ ) { if( ite->getInitFlag() ) continue; ite->setInitFlag( true ); _tcscpy( tTitle, ite->getFileName().c_str() ); lvi.pszText = tTitle; lvi.cchTextMax = MAX_PATH; iItem = ListView_InsertItem( m_hWndList, &lvi ); lvi.iItem++; ite->setIndex( iItem ); } if( m_curNum == -1 ) { m_curNum = 0; ListView_SetHotItem( m_hWndList, m_curNum ); } } ////////////////////////////////// //跳到下一首 void PlayList::gotoNext() { int count = ListView_GetItemCount( m_hWndList ); if( count == 0 ) { return; } m_curNum = ListView_GetHotItem( m_hWndList ); m_curNum++; if( m_curNum >= count ) { m_curNum = 0; } ListView_SetHotItem( m_hWndList, m_curNum ); } ////////////////////////////////// //跳至上一首 void PlayList::gotoPrev() { int count = ListView_GetItemCount( m_hWndList ); if( count == 0 ) { return; } m_curNum = ListView_GetHotItem( m_hWndList ); m_curNum--; if( m_curNum < 0 ) { m_curNum = count - 1; } ListView_SetHotItem( m_hWndList, m_curNum ); } ////////////////////////////////// //获取当前用户选择的文件路径 string PlayList::getCurFilePath() { int count = ListView_GetItemCount( m_hWndList ); if( count == 0 ) { return _T(""); } int curItem = ListView_GetHotItem( m_hWndList ); vector<FileInfo>::iterator ite; for( ite = m_vecFile.begin(); ite != m_vecFile.end(); ite++ ) { if( ite->getIndex() == curItem ) { return ite->getPath(); } } return _T(""); } //////////////////////////////////// //删除所选项目 void PlayList::RemSel() { vector<FileInfo>::iterator ite; int i; int delcount = 0; for( ite = m_vecFile.begin(); ite != m_vecFile.end(); ite++ ) { i = ite->getIndex(); i -= delcount; ite->setIndex( i ); if( ListView_GetItemState( m_hWndList, i, LVIS_SELECTED ) ) { ListView_DeleteItem( m_hWndList, i ); m_vecFile.erase( ite ); ite--; delcount++; } } } /////////////////////////////////////// //删除未被选择项目 void PlayList::RemUnSel() { vector<FileInfo>::iterator ite; int i; int delcount = 0; for( ite = m_vecFile.begin(); ite != m_vecFile.end(); ite++ ) { i = ite->getIndex(); i -= delcount; ite->setIndex( i ); if( ! ListView_GetItemState( m_hWndList, i, LVIS_SELECTED ) ) { ListView_DeleteItem( m_hWndList, i ); m_vecFile.erase( ite ); ite--; delcount++; } } } /////////////////////////////////////// //反选 void PlayList::UnSel() { int count = ListView_GetItemCount( m_hWndList ); UINT isSel; LVITEM lvi; for( int i = 0; i < count; i++ ) { isSel = ListView_GetItemState( m_hWndList, i, LVIS_SELECTED ); if( isSel ) { lvi.iItem = i; lvi.mask = LVIF_STATE; lvi.state = 0; lvi.stateMask = LVIS_SELECTED; ListView_SetItem( m_hWndList, &lvi ); } } } /////////////////////////////////////// //选择全部 void PlayList::SelAll() { int count = ListView_GetItemCount( m_hWndList ); LVITEM lvi; for( int i = 0; i < count; i++ ) { lvi.iItem = i; lvi.mask = LVIF_STATE; lvi.state = LVIS_SELECTED; lvi.stateMask = LVIS_SELECTED; ListView_SetItem( m_hWndList, &lvi ); } } /////////////////////////////////////// //选择其他 void PlayList::SelOther() { int count = ListView_GetItemCount( m_hWndList ); UINT isSel; LVITEM lvi; for( int i = 0; i < count; i++ ) { isSel = ListView_GetItemState( m_hWndList, i, LVIS_SELECTED ); if( !isSel ) { lvi.iItem = i; lvi.mask = LVIF_STATE; lvi.state = LVIS_SELECTED; lvi.stateMask = LVIS_SELECTED; ListView_SetItem( m_hWndList, &lvi ); } else { lvi.iItem = i; lvi.mask = LVIF_STATE; lvi.state = 0; lvi.stateMask = LVIS_SELECTED; ListView_SetItem( m_hWndList, &lvi ); } } }